package com.yz.yrpc.config;


import com.yz.yrpc.annotation.Yrpc;
import com.yz.yrpc.annotation.YrpcClient;
import com.yz.yrpc.handler.ParamHandler;
import com.yz.yrpc.handler.ResultHandler;
import com.yz.yrpc.util.ClassUtil;
import okhttp3.*;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Map;

/**
 * @author shanchong
 * @date 2019-06-30
 **/
public class RpcInvocationHandler implements InvocationHandler {

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Yrpc annotation = method.getAnnotation(Yrpc.class);
        final YrpcClient[] annotationsByType = method.getDeclaringClass().getAnnotationsByType(YrpcClient.class);
        final YrpcClient yrpcClient = annotationsByType[0];
        if (annotation==null){
            return null;
        }

        OkHttpClient okHttpClient = new OkHttpClient.Builder().build();
        Request.Builder builder = new Request.Builder();

        final Class<?> paramHandlerClass = yrpcClient.paramHandler();
        final ParamHandler paramHandler = (ParamHandler) paramHandlerClass.newInstance();
        final String httpMethod = annotation.method();
        Map<String,Object> paramMap = paramHandler.handle(args);
        if ("GET".equals(httpMethod)) {
            HttpUrl.Builder httpUrl = HttpUrl.parse(annotation.url()).newBuilder();
            paramMap.forEach((k,v)->{
                httpUrl.addQueryParameter(k,v.toString());
            });
            builder.url(httpUrl.build()).method(httpMethod,null);
        }else if ("POST".equals(httpMethod)){
            final FormBody.Builder formBody = new FormBody.Builder();
            paramMap.forEach((k,v)->{
                formBody.add(k,v.toString());
            });
            builder.url(annotation.url()).method(httpMethod,formBody.build());
        }
        Call call = okHttpClient.newCall(builder.build());
        Response response = call.execute();
        String result = response.body().string();
        final Class<?> resultHandlerClass = yrpcClient.resultHandler();
        final ResultHandler resultHandler = (ResultHandler) resultHandlerClass.newInstance();
        return resultHandler.handle(result);
    }


}
